﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Microsoft.SharePoint.Administration;
using System.IdentityModel.Tokens;
using Microsoft.SharePoint;
using Microsoft.SharePoint.IdentityModel;

namespace WindowsSignInPage
{
    public class Authentication
    {
        const string Sp2010_WindowsSignedIn = "SP2010_WindowsSignedIn";
        const string Sp2010_KeepSessionAuthenticated = "WSS_KeepSessionAuthenticated";
        const string Sp2010_AnonymousAccessCookie = "MSOWebPartPage_AnonymousAccessCookie";
        const string Sp2010_Auth = "FedAuth";

        protected static SiteConfig config = SiteConfig.Load();
        protected static SSOService.Auth SSO;
        protected static HttpContext Context
        {
            get { return HttpContext.Current; }
        }
        protected static string SharePointUrl
        {
            get
            {
                return config.ApplicationUrl;
            }
        }
       
         static Authentication()
        {
            SSOService.Auth auth = new SSOService.Auth();
            auth.Url = config.SSOServiceUrl;
            SSO = auth;
        }
        public static string GetLogonUrl()
        {
            return SSO.GetLogonUrl(config.SharePointUrl);
        }
        public static string GetLogoutUrl()
        {
            return SSO.GetLogoutUrl("");
        }
        public static string GetCurrentUser()
        {
            string cookieValue = string.Empty;

            HttpRequest Request = HttpContext.Current.Request;

            for (int i = 0; i < Request.Cookies.Count; i++)
            {
                if (Request.Cookies[i].Name.CompareTo("iPlanetDirectoryPro") == 0)
                {
                    cookieValue = Request.Cookies[i].Value;
                }
            }

            if (string.IsNullOrEmpty(cookieValue))
                return string.Empty;

            //Get cookie value
            return GetCurrentUser(cookieValue);
        }
        public static bool IsAuthed
        {
            get
            {
                string authCookie = HttpContext.Current.Request["FedAuth"];
                return !string.IsNullOrEmpty(authCookie);
            }
        }
        public static string GetCurrentUser(string cookieValue)
        {
            return SSO.GetCurrentUser(cookieValue);
        }

        public static void RemoveCookiesAndSignOut()
        {
            // Clear session state. 
            if (Context.Session != null)
            {
                Context.Session.Clear();
            }

            string cookieValue = string.Empty;
            if (Context.Request.Browser["supportsEmptyStringInCookieValue"] == "false")
                cookieValue = "NoCookie";

            // Clear my own cookie.
            //HttpCookie cookieWinSignIn = Context.Request.Cookies[Sp2010_WindowsSignedIn];
            //if (cookieWinSignIn != null)
            //{
            //    cookieWinSignIn.Value = cookieValue;
            //    Context.Response.Cookies.Remove(Sp2010_WindowsSignedIn);
            //    Context.Response.Cookies.Add(cookieWinSignIn);
            //}

            // Remove cookies for authentication. 
            HttpCookie cookieSession = Context.Request.Cookies[Sp2010_KeepSessionAuthenticated];
            if (cookieSession != null)
            {
                cookieSession.Value = cookieValue;
                Context.Response.Cookies.Remove(Sp2010_KeepSessionAuthenticated);
                Context.Response.Cookies.Add(cookieSession);
            }

            HttpCookie cookiePersist = Context.Request.Cookies[Sp2010_AnonymousAccessCookie];
            if (cookiePersist != null)
            {
                cookiePersist.Value = cookieValue;
                cookiePersist.Expires = new DateTime(1970, 1, 1);
                Context.Response.Cookies.Remove(Sp2010_AnonymousAccessCookie);
                Context.Response.Cookies.Add(cookiePersist);
            }
            HttpCookie cookieAuth = Context.Request.Cookies["FedAuth"];
            if (cookieAuth != null)
            {
                cookieAuth.Value = cookieValue;
                cookieAuth.Expires = new DateTime(1970, 1, 1);
                Context.Response.Cookies.Remove(Sp2010_Auth);
                Context.Response.Cookies.Add(cookieAuth);
            }
            // Sign out.
            Microsoft.IdentityModel.Web.FederatedAuthentication.SessionAuthenticationModule.SignOut();
        }

        public static void SuccessLogin(string username, string password)
        {
            SecurityToken token = GetSecurityToken(username, password);
            //SecurityToken token = WindowsContext.Instance.GetToken(username, "ceibs.edu", password);
            EstablishSessionWithToken(token);
        }

        public static SecurityToken GetSecurityToken(string userName, string password)
        {
            SPIisSettings iisSettings = IisSettings;

            //Uri appliesTo = base.AppliesTo;
            Uri appliesTo = new Uri(SharePointUrl);

            SPFormsAuthenticationProvider authProvider = iisSettings.FormsClaimsAuthenticationProvider;
            SecurityToken token = SPSecurityContext.SecurityTokenForFormsAuthentication(
                appliesTo,
                authProvider.MembershipProvider,
                authProvider.RoleProvider,
                userName,
                password);

            return token;
        }


        private static void EstablishSessionWithToken(SecurityToken securityToken)
        {
            if (null == securityToken)
            {
                throw new ArgumentNullException("securityToken");
            }
            SPFederationAuthenticationModule fam = SPFederationAuthenticationModule.Current;
            if (null == fam)
            {
                throw new ArgumentException(null, "FederationAuthenticationModule");
            }
            fam.SetPrincipalAndWriteSessionToken(securityToken);
        }

        private static SPIisSettings IisSettings
        {

            get
            {
                SPWebApplication webApp = null;
                try
                {
                    //WriteLog("SPContext.Current.Web.Url:-" + SPContext.Current.Web.Url);
                    //webApp = SPContext.Current.Site.WebApplication;
                    webApp = SPWebApplication.Lookup(new Uri(SharePointUrl));
                }
                catch (Exception ex)
                {
                    //Logger.Error("webAPP is null", ex);
                }
                SPIisSettings settings = webApp.IisSettings[SPUrlZone.Default];
                return settings;
            }
        }


        public static void LogLogin()
        {
            UserLog log = new UserLog() { LoginId = GetCurrentUser(), Comments = "Login" };
            log.Save();
        }

        public static void LogUploadFile(string[] fileNames)
        {
            UserLog log = new UserLog() { LoginId = GetCurrentUser(), Comments = "Upload files:" + string.Join(",", fileNames) };
            log.Save();
        }

        public static void DownloadFile(string fileName)
        {
            UserLog log = new UserLog() { LoginId = GetCurrentUser(), Comments = "Download file:" + fileName };
            log.Save();
        }
    }
}
